// 版权所有 Epic Games, Inc. 保留所有权利。

#pragma once

#include "ReplicationGraphTypes.h"
#include "LyraReplicationGraphTypes.generated.h"

// 这是用于将Actor路由到正确复制节点的主要枚举。每个类映射到一个枚举。
UENUM()
enum class EClassRepNodeMapping : uint32
{
	NotRouted,						// 不映射到任何节点。用于由特殊 case 节点处理的特殊 case Actor（例如 ULyraReplicationGraphNode_PlayerStateFrequencyLimiter）
	RelevantAllConnections,			// 路由到 AlwaysRelevantNode 或 AlwaysRelevantStreamingLevelNode 节点

	// 以下仅为空间化枚举！参见 ULyraReplicationGraph::IsSpatialized

	Spatialize_Static,				// 路由到 GridNode：这些 Actor 不移动，不需要每帧更新。
	Spatialize_Dynamic,				// 路由到 GridNode：这些 Actor 频繁移动，每帧更新一次。
	Spatialize_Dormancy,			// 路由到 GridNode：处于休眠状态时视为静态。当刷新/非休眠时视为动态。注意这是针对那些“在非休眠时移动”的对象。
};

// 可以直接分配给类的 Actor 类设置。也可以映射到 FRepGraphActorTemplateSettings
USTRUCT()
struct FRepGraphActorClassSettings
{
	GENERATED_BODY()

	FRepGraphActorClassSettings() = default;

	// 将应用此设置的类的名称
	UPROPERTY(EditAnywhere)
	FSoftClassPath ActorClass; // Actor类路径

	// 是否应将此类的 RepInfo 添加到 ClassRepNodePolicies 映射中
	UPROPERTY(EditAnywhere, meta = (InlineEditConditionToggle))
	bool bAddClassRepInfoToMap  = true; // 是否将类Rep信息添加到映射

	// 当将类添加到 ClassRepNodePolicies 映射时，应使用的 ClassNodeMapping
	UPROPERTY(EditAnywhere, meta = (EditCondition = "bAddClassRepInfoToMap"))
	EClassRepNodeMapping ClassNodeMapping = EClassRepNodeMapping::NotRouted; // 类复制节点映射

	// 是否将此添加到 RPC_Multicast_OpenChannelForClass 映射中
	UPROPERTY(EditAnywhere, meta = (InlineEditConditionToggle))
	bool bAddToRPC_Multicast_OpenChannelForClassMap = false; // 是否添加到RPC多播开放通道类映射

	// 如果将此添加到 RPC_Multicast_OpenChannelForClass 映射中，是否实际打开通道
	UPROPERTY(EditAnywhere, meta = (EditCondition = "bAddToRPC_Multicast_OpenChannelForClassMap"))
	bool bRPC_Multicast_OpenChannelForClass = true; // 是否为类启用RPC多播开放通道

	/**
	 * 获取静态Actor类对象
	 * @return 找到的UClass*，如果未找到则返回nullptr并记录错误
	 */
	UClass* GetStaticActorClass() const
	{
		UClass* StaticActorClass = nullptr;
		const FString ActorClassNameString = ActorClass.ToString();

		if (FPackageName::IsScriptPackage(ActorClassNameString))
		{
			StaticActorClass = FindObject<UClass>(nullptr, *ActorClassNameString, true);

			if (!StaticActorClass)
			{
				UE_LOG(LogTemp, Error, TEXT("FRepGraphActorClassSettings: 无法找到 %s 的静态类"), *ActorClassNameString);
			}
		}
		else
		{
			// 允许使用蓝图进行自定义类设置
			StaticActorClass = (UClass*)StaticLoadObject(UClass::StaticClass(), nullptr, *ActorClassNameString);
			if (!StaticActorClass)
			{
				UE_LOG(LogTemp, Error, TEXT("FRepGraphActorClassSettings: 无法加载 %s 的静态类"), *ActorClassNameString);
			}
		}

		return StaticActorClass;
	}
};